package com.tju.driver

import com.example.x6.serial.SerialPort
import java.io.File
import java.util.*
import java.util.concurrent.locks.ReentrantLock
import kotlin.collections.HashMap

object SerialManager {
    private val serialContext = SerialPort( File("/dev/ttyS2"),9600,0)
    private val inputStream = serialContext.inputStream
    private val outputStream = serialContext.outputStream
    private val sendQueue: Queue<Byte> = LinkedList()
    private val queueLock = ReentrantLock()
    private val queueCondition = queueLock.newCondition()

    private val addressMap: HashMap<Byte, HashMap<Byte, SerialHandler>> = HashMap()
    private val recieveBuffer: LinkedList<Byte> = LinkedList()

    private var started = false

    fun start() {
        queueLock.lock()
        if(started) return
        started = true
        Thread { //发送线程
            while (true) {
                if (sendQueue.isEmpty()) {
                    queueCondition.await()
                } else {
                    val curByte = sendQueue.poll()!!
                    //发送当前字节
//                    println("发送字节 $curByte")
                    outputStream.write(byteArrayOf(curByte))
                }
            }
        }.start()
        Thread { //接收线程
            while (true) {
                val rec = inputStream.read().toByte()
                handler(rec)
            }
        }.start()
        queueLock.unlock()
    }

    private fun handler(rec: Byte) {
        if (recieveBuffer.isEmpty() && rec==0xCC.toByte()) {
            recieveBuffer.add(rec)
        } else if (recieveBuffer.size==1) {
            if (rec>0 && rec<0x10.toByte() && addressMap.containsKey(rec)) {
                recieveBuffer.add(rec)
            } else {
                recieveBuffer.clear()
            }
        } else if (recieveBuffer.size==2) {
            if (rec>0x10.toByte() && rec<0x20.toByte()
                    && addressMap.containsKey(recieveBuffer[1])
                    && addressMap[recieveBuffer[1]]!!.containsKey(recieveBuffer[2])) {
                addressMap[recieveBuffer[1]]!![recieveBuffer[2]]!!.handle(rec)
            } else {
                recieveBuffer.clear()
            }
        }
    }

    fun sendData(bytes: Array<Byte>) {
        queueLock.lock()
        bytes.forEach { sendQueue.add(it) }
        queueCondition.signalAll()
        queueLock.unlock()
    }

    fun sendByte(byte: Byte) {
        outputStream.write(byteArrayOf(byte))
    }
}